﻿using LPBToolsLib;
using LPBToolsLib.NetSocket;
using LPBToolsNF.NetSocket;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using StationSer;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace StationNF
{

    /// <summary>
    /// JSON命令服务器
    /// 提供JSON命令响应，基于TCP/IP服务程序
    /// </summary>
    public class JCommandServer : TCPAsyncServer
    {
        public StationsServer tPLCStationsSer { get; set; } = null;

        public JCommandServer(StationsServer DestBusServer)
        {
            if (DestBusServer != null)
            {
                tPLCStationsSer = DestBusServer;
                base.OnReceive += CommandServer_OnReceive;
            }
        }

        private void CommandServer_OnReceive(object sender, System.Net.Sockets.Socket ClientSocket, ref byte[] RecData)
        {
            if ((RecData != null) && (RecData.Length > 0))
            {
                string sInfo = "";
                try
                {
                    sInfo = Encoding.UTF8.GetString(RecData);
                    Dictionary<string, object> tRecCommands = null;
                    Dictionary<string, object> tRespons = new Dictionary<string, object>();
                    if ((!string.IsNullOrEmpty(sInfo)) && sInfo.StartsWith("{") && sInfo.EndsWith("}"))
                        tRecCommands = JsonConvert.DeserializeObject<Dictionary<string, object>>(sInfo);

                    RecData = null;
                    sInfo = "";
                    if ((tRecCommands != null) && (tRecCommands.Count > 0))
                    {
                        if (runWithCommand(tRecCommands, tRespons))
                            sInfo = JsonConvert.SerializeObject(tRespons);
                    }
                    if (!string.IsNullOrEmpty(sInfo))
                    {
                        RecData = Encoding.UTF8.GetBytes(sInfo);
                    }
                }
                catch (Exception ex)
                {
                    ErrRecorder?.setRecord(ex);
                }
            }
        }

        public bool runWithCommand(Dictionary<string, object> tRecCommands,
            Dictionary<string, object> tRespons)
        {
            tRespons.Clear();
            tRespons.Add("err", 0);
            tRespons.Add("msg", "ok");
            if ((tRecCommands != null) && (tRecCommands.Count > 0))
            {
                try
                {
                    foreach (KeyValuePair<string, object> Command in tRecCommands)
                    {
                        switch (Command.Key.ToLower())
                        {
                            case "getserialportlist":
                                tRespons.Add("SerialPortList", SerialPort.GetPortNames());
                                break;
                            case "getiplist":
                                IPAddress[] tIPList = TCPServerSocket.getIpAddressList();
                                List<string> sIPList = new List<string>();
                                foreach (IPAddress IP in tIPList)
                                    sIPList.Add(IP.ToString());
                                tRespons.Add("IPList", sIPList.ToArray());
                                break;
                            
                            case "getstationlist":
                                if (tPLCStationsSer != null)
                                {
                                    string[] PLCAddrList = tPLCStationsSer.StationsIDList;
                                    Dictionary<string, Dictionary<string, object>> tPLCListInfo = new Dictionary<string, Dictionary<string, object>>();
                                    foreach (string PLCStationID in PLCAddrList)
                                    {
                                        IFDExCommunicater tDExCommunicater = tPLCStationsSer.getCommunicater(PLCStationID);
                                        if (tDExCommunicater != null)
                                        {
                                            IFStation tPLCStation = tDExCommunicater.Station;
                                            if (tPLCStation != null)
                                            {
                                                Dictionary<string, object> tPLCInfos = tPLCStation.getStationStatus();
                                                if (tPLCInfos.ContainsKey("StaID"))
                                                    tPLCInfos.Remove("StaID");
                                                tPLCListInfo.Add(PLCStationID, tPLCInfos);
                                            }
                                        }
                                    }
                                    tRespons.Add("StaInfoList", tPLCListInfo);
                                }
                                else
                                {
                                    tRespons["err"] = -1;
                                    tRespons["msg"] = "BusServer is null!";
                                }
                                break;                            
                            case "getstationruninfo":   // Value存放StatioinID
                                if (tPLCStationsSer != null)
                                {
                                    Dictionary<string, object> tInfo = null;
                                    IFDExCommunicater tDExCommunicater = tPLCStationsSer.getCommunicater(Command.Value.ToString());
                                    if (tDExCommunicater!=null)
                                    {
                                        IFStation tPLCStatioin = tDExCommunicater.Station;
                                        tInfo = tPLCStatioin.getStationStatus();
                                        tInfo.Add("RegValues", tPLCStatioin.RegValues);
                                        tRespons.Add("StaRunInfo", tInfo);
                                    }
                                }
                                else
                                {
                                    tRespons["err"] = -1;
                                    tRespons["msg"] = "StationsSer is null!";
                                }
                                break;
                            case "setstationport":
                                if (tPLCStationsSer != null)
                                {
                                    Dictionary<string, object> tInfo = null;
                                    IFDExCommunicater tDExCommunicater = tPLCStationsSer.getCommunicater(Command.Value.ToString());
                                    if ((tDExCommunicater != null)&&(tDExCommunicater.Station!=null))
                                    {
                                        int iPortIdx = 0;
                                        int iPortValue = 0;
                                        if (tRecCommands.ContainsKey("PortIndex") && (tRecCommands.ContainsKey("PortValue"))
                                            && int.TryParse(tRecCommands["PortIndex"].ToString(), out iPortIdx)
                                            && int.TryParse(tRecCommands["PortValue"].ToString(), out iPortValue)
                                            && (iPortIdx >= 0) && (iPortValue >= 0))
                                        {
                                            // 操作下位机指定端口
                                            DExOption_DownLoadWriteOn_0x05 tOptWrite0x05 = new DExOption_DownLoadWriteOn_0x05();
                                            tOptWrite0x05.YIndex = (byte)iPortIdx;
                                            tOptWrite0x05.Value = (iPortValue==1);
                                            tDExCommunicater.Station.setResponCommand(tOptWrite0x05);
                                        }
                                        tInfo = tDExCommunicater.Station.getStationStatus();
                                        tRespons.Add("StaRunInfo", tInfo);
                                    }
                                }
                                else
                                {
                                    tRespons["err"] = -1;
                                    tRespons["msg"] = "StationsSer is null!";
                                }
                                break;
                            case "setstationreg":
                                if (tPLCStationsSer != null)
                                {
                                    Dictionary<string, object> tInfo = null;
                                    IFDExCommunicater tDExCommunicater = tPLCStationsSer.getCommunicater(Command.Value.ToString());
                                    if (tDExCommunicater != null)
                                    {
                                        IFStation tPLCStatioin = tDExCommunicater.Station;
                                        int iRegStar = 0;
                                        ushort[] iRegValue = null;
                                        if (tRecCommands.ContainsKey("RegStar") && (tRecCommands.ContainsKey("RegValue"))
                                            && int.TryParse(tRecCommands["RegStar"].ToString(), out iRegStar)
                                            && (iRegStar >= 0))
                                        {

                                            // 操作下位机指定寄存器
                                            DExOption_DownLoadWriteReg_0x10 tOptWrite0x10 = new DExOption_DownLoadWriteReg_0x10();
                                            //tOptWrite0x10.DownLoadWriteRegStarAddr

                                        }
                                        tInfo = tPLCStatioin.getStationStatus();
                                        tRespons.Add("StaRunInfo", tInfo);
                                    }
                                }
                                else
                                {
                                    tRespons["err"] = -1;
                                    tRespons["msg"] = "StationsSer is null!";
                                }
                                break;
                        }
                    }
                }
                catch (Exception ex)
                {
                    ErrRecorder?.setRecord(ex);
                }
                List<string> tErrList = new List<string>();
                if ((ErrRecorder != null) && (ErrRecorder.RecCount > 0))
                {
                    tRespons["err"] = -ErrRecorder.RecCount;
                    tRespons["msg"] = ErrRecorder.getAllErrorStr();
                }
                return true;
            }
            return false;
        }
    }


}
